package com.telecomyt.jwportal.base;

import android.content.Context;

import com.telecomyt.jwportal.base.i.IBaseModel;
import com.telecomyt.jwportal.base.i.IBaseView;
import com.trello.rxlifecycle2.LifecycleProvider;
import com.trello.rxlifecycle2.android.ActivityEvent;

import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public abstract class BasePresenter<M extends IBaseModel, V extends IBaseView> {
    private WeakReference<IBaseView> weakReference;
    private V mProxyView;
    private M module;
    private LifecycleProvider<ActivityEvent> provider;

    public BasePresenter(LifecycleProvider<ActivityEvent>provider){
        this.provider=provider;
    }

    public LifecycleProvider<ActivityEvent> getProvider() {
        return provider;
    }

    public void setProvider(LifecycleProvider<ActivityEvent> provider) {
        this.provider = provider;
    }
    public void attacView(IBaseView view) {
        weakReference = new WeakReference<>(view);
        mProxyView = (V) Proxy.newProxyInstance
                (view.getClass().getClassLoader()
                        , view.getClass().getInterfaces(),
                        new MvpViewHandler(view));
        if (this.module == null) {
            this.module = creatModule();
        }
    }

    protected V getView() {
        return mProxyView;
    }

    protected M getModule() {
        return module;
    }

    protected Context getContext() {
        return getView().getContext();
    }

    public void detachView() {
        if (weakReference != null) {
            weakReference.clear();
            weakReference = null;
        }
    }


    protected boolean isViewAttached() {
        return weakReference != null && weakReference.get() != null;
    }

    protected abstract M creatModule();

    /**
     * View代理类  防止 页面关闭P异步操作调用V 方法 空指针问题
     */
    private class MvpViewHandler implements InvocationHandler {

        private IBaseView mvpView;

        MvpViewHandler(IBaseView mvpView) {
            this.mvpView = mvpView;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //如果V层没被销毁, 执行V层的方法.
            if (isViewAttached()) {
                return method.invoke(mvpView, args);
            } //P层不需要关注V层的返回值
            return null;
        }
    }
}
